#ifndef GAME_H
#define GAME_H

#include "SDL.h"
#include "SDL_ttf.h"
#include <string>
#include <vector>
#include <memory>

#include "snake.h"
#include "theme.h"
#include "map.h"
#include "renderer.h"

class Game
{
public:
    Game();
    ~Game();
    void create_renderLastWindow(int lastWindowIndex);

    void createInformationBoard();
    void InformationBoardKeyboard(int selectedOption, std::vector<SDL_Texture*> InformationBoardKey, Renderer renderer);
    void renderInformationBoard();

    void createGameBoard();
    void renderGameBoard();
    void renderCountdown(Renderer renderer);

    void createPauseBoard();
    void PauseBoardKeyboard(int selectedOption, std::vector<SDL_Texture*> PauseBoard, Renderer renderer);
    void renderPauseBoard();

    void createShopBoard();
    void ShopBoardKeyboard(bool area, int selectedOption, std::vector<SDL_Texture*> ShopBoard, Renderer renderer);
    void renderShopBoard();

    void GameKeyBoard(SDL_Event& event, bool& GameRunning);
    void runGame(Renderer renderer);
    int restartGame(Renderer renderer, SDL_Texture* backbuffer);
    void endGame();

    void renderPoints(Renderer renderer, SDL_Rect rect, SDL_Color placeColor);
    void renderBarriers(Renderer renderer);

    void createScoreBoard();
    void renderScores(Renderer renderer);
    void renderScoreBoard();

    void createInstructionBoard();
    void renderInstructionBoard();

    bool readScoreBoard();
    bool updateScoreBoard();
    bool writeScoreBoard();

    void controlSnake(SDL_Event event) const;
    void renderSnake(Renderer renderer);

    bool isPartOfWall(const int x, const int y) const;
    void createRandomFood();
    void renderFood(Renderer renderer);
    void DestroyFood(int i, Renderer renderer);

    void startGame();
    void adjustDelay(int& frameDelay);

    void initializeGame(Renderer renderer);

    void chooseMap(Renderer renderer);

    void loadTexture(std::string imagePath, std::vector<SDL_Texture*>& Textures, Renderer renderer);

    void loadGameTexture(Renderer renderer);

private:
    // We need to have two windows
    // One is for game introduction
    // One is for game mWindows
    std::vector<SDL_Window*> mWindows;
    //std::vector<SDL_Renderer*> mRenderers;
    SDL_DisplayMode DM;
    int mScreenWidth;
    int mScreenHeight;
    int mGameBoardWidth;
    int mGameBoardHeight;
    int mInstructionWidth;
    int mInstructionHeight;
    int mInformationWidth;
    int mInformationHeight;
    int mScoreBoardWidth;
    int mScoreBoardHeight;
    int mInstructionBoardWidth;
    int mInstructionBoardHeight;
    int mPauseBoardWidth;
    int mPauseBoardHeight;
    int mShopBoardWidth;
    int mShopBoardHeight;
    std::vector<int> windowTree = {};
    TTF_Font* font = NULL;
    //Theme Information
    Theme GameTheme;
    // Snake information
    //const int mInitialSnakeLength = 2;
    std::unique_ptr<Snake> mPtrSnake;

    // Food information
    int FoodNums = 0;
    std::vector<point> mFoods;
    //Score information
    int mPoints = 0;
    int mDifficulty = 0;
    int mBaseDelay = 100;
    int mDelay;
    const std::string mRecordBoardFilePath = "./data/record.dat";
    std::vector<int> mScoreBoard;
    const int mNumLeaders = 5;
    //Board information
    Map GameMap;
    std::map<Direction, int> DirectionMap = { {Direction::Up, 0}, {Direction::Right, 90}, {Direction::Down, 180} ,{Direction::Left, 270} };
    std::map<std::string, double> mMap;
    std::vector<point> mBarriers;
    std::map <std::string, std::vector<SDL_Texture*>> TextureMap;
    bool GamePause = false;
};

#endif
